home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 2
/
Nebula Two.iso
/
SourceCode
/
Database
/
AddressBook
/
Controller.m
< prev
next >
Wrap
Text File
|
1995-06-12
|
7KB
|
273 lines
/* Controller.m:
* You may freely copy, distribute, and reuse the code in this example.
* NeXT disclaims any warranty of any kind, expressed or implied, as to its
* fitness for any particular use.
*
* Written by: Mai Nguyen, NeXT Developer Support
*
*
*/
#import <appkit/appkit.h>
#import <dbkit/dbkit.h>
#import <objc/List.h>
#import <objc/NXBundle.h>
#import <sys/param.h>
#import <libc.h>
#import "Controller.h"
#import "AddressView.h"
#define FAILURE NXLocalizedString("Failure:", NULL, "Message given to user when connection to database can't be made")
#define CANNOT_CONNECT NXLocalizedString("Couldn't connect to database", NULL, "Message given to user to explain what fails. ")
#define CANNOT_ADD NXLocalizedString("Add operation failed", NULL, "Message given to user that add operation has failed")
#define CANNOT_UPDATE NXLocalizedString("Update operation failed",NULL,"Message given to user that update operation has failed")
#define CANNOT_DELETE NXLocalizedString("Delete operation failed",NULL,"Message given to user that delete operation has failed")
@implementation Controller
- appDidInit:sender
{
/* Try to connect to the database specified using the Sybase Adaptor
* and the default login sa, NULL password, SYBASE server, and
* pubs database.
*/
database = [[DBDatabase alloc]init];
[database connectUsingAdaptor:"SybaseAdaptor"
andString:"sa@SYBASE/pubs"];
if ( ![database isConnected] ) {
NXRunAlertPanel(FAILURE, CANNOT_CONNECT, "OK", NULL, NULL);
return self;
}
/* Once successfully connected, build the data to be displayed in the
* matrix
*/
[self initRecordList];
[addressView loadCellsFrom:self];
/* Assign the controller to become the database delegate */
[database setDelegate:self];
cellMatrix = [addressView cellMatrix];
/* Select a cell as a start */
[[cellMatrix selectCellAt:0 :0] sendAction];
/* Bring the main application window up front */
[theWindow makeKeyAndOrderFront:nil];
return self;
}
/* Set up the DBRecordList object. Create a list of properties which contains
* all properties needed for display or updating.
*/
- initRecordList
{
id firstName, lastName, phone;
id state, city, address, zipCode, contract;
List *keyList;
if (recordList)
[recordList free];
if (propertyList)
[propertyList free];
/* get the author table from the database */
authorEntity = [database entityNamed:"authors"];
/* get the properties */
lastName = [authorEntity propertyNamed:"au_lname"];
firstName = [authorEntity propertyNamed:"au_fname"];
authId = [authorEntity propertyNamed:"au_id"];
phone = [authorEntity propertyNamed:"phone"];
address = [authorEntity propertyNamed:"address"];
city = [authorEntity propertyNamed:"city"];
state = [authorEntity propertyNamed:"state"];
zipCode = [authorEntity propertyNamed:"zip"];
contract = [authorEntity propertyNamed:"contract"];
/* Set up the property list
* Note that certain properties need to be defined in order
* for an Insert or Update operation to work. This depends
* on how your data dictionary has been defined. Here pubs
* is being used as the model.
*/
propertyList = [[List alloc] init];
[propertyList addObject:authId];
[propertyList addObject:lastName];
[propertyList addObject:firstName];
[propertyList addObject:phone];
[propertyList addObject:address];
[propertyList addObject:city];
[propertyList addObject:state];
[propertyList addObject:zipCode];
[propertyList addObject:contract];
recordList = [[DBRecordList alloc] init];
/* A unique key is needed if you want to update or insert new
* data via the record list into the database. If no key is defined,
* the data retrieved via the record list is read-only.
* This is needed here, since we do not use a dbmodel to define
* the key.
*/
keyList = (List *)[[List alloc] init];
[keyList addObject:authId];
[recordList setKeyProperties:keyList];
[keyList free];
/* You must set the properties FIRST before setting the retrieve order */
[recordList setProperties:propertyList ofSource:authorEntity];
[recordList addRetrieveOrder:DB_AscendingOrder for:lastName];
[recordList addRetrieveOrder:DB_AscendingOrder for:firstName];
[recordList fetchUsingQualifier:nil];
recordCount = [recordList count];
return self;
}
/* This method is called when selecting "Insert"
*/
- addRecords:sender
{
int row;
if (recordCount > 0) {
if ( ![addressView addRecordFrom:sender at:(recordCount-1)]) {
NXRunAlertPanel(NULL, CANNOT_ADD, NULL, NULL, NULL);
return self;
}
[self initRecordList];
[addressView loadCellsFrom:self];
/* Find the row of the newly inserted record */
row = [addressView getNewRow];
[cellMatrix scrollCellToVisible:row :0];
[[cellMatrix selectCellAt:row:0] sendAction];
}
else
fprintf(stderr, "empty record list - NOP\n");
return self;
}
/* This method gets called when selecting "Update"
*/
- updateRecords:sender
{
int row;
row = [cellMatrix selectedRow];
if ( ![addressView updateRecordFrom:sender at:row]) {
NXRunAlertPanel(NULL, CANNOT_UPDATE, NULL, NULL, NULL);
return self;
}
/* Redisplay the records */
[self initRecordList];
[addressView loadCellsFrom:self];
/* find the row of the updated record */
row = [addressView getNewRow];
[cellMatrix scrollCellToVisible:row :0];
[[cellMatrix selectCellAt:row:0] sendAction];
return self;
}
- deleteRecords:sender
{
int row;
row = [cellMatrix selectedRow];
if (recordCount > 0) {
if (![addressView deleteSelectedRecord:sender]) {
NXRunAlertPanel(NULL, CANNOT_DELETE, NULL, NULL, NULL);
return self;
}
[self initRecordList];
[addressView loadCellsFrom:self];
[cellMatrix scrollCellToVisible:row :0];
[[cellMatrix selectCellAt:row:0] sendAction];
}
else
fprintf(stderr, "empty record list - NOP\n");
return self;
}
- getRecordList
{
return recordList;
}
- getPropertyList
{
return propertyList;
}
- (int)getRecordCount
{
return recordCount;
}
- showSQLPanel:sender
{
[SQLPanel makeKeyAndOrderFront:nil];
return self;
}
- showInfoPanel:sender
{
if (!infoPanel) {
infoPanel = [NXApp loadNibSection:"InfoPanel.nib" owner:NXApp
withNames:NO];
}
[infoPanel orderFront:nil];
return self;
}
- appWillTerminate:sender
{
/* deallocate what has been allocated */
if (recordList)
[recordList free];
if (propertyList)
[propertyList free];
return self;
}
/* DBDatabase delegate methods to log error messages and SQL queries */
- (BOOL)db:aDb willEvaluateString:(const unsigned char*)aString
usingBinder:aBinder
{
[textObj appendToText:"SQL Query:\n"];
[textObj appendToText:aString];
[textObj appendToText:"\n"];
return YES;
}
@end
@implementation Text(printResults)
- appendToText:(const char *)newText
{
int currentLength = [self textLength];
[self setSel:currentLength :currentLength];
[self replaceSel:newText];
[self scrollSelToVisible];
return self;
}
@end